﻿#include "naluloop.h"
#include "easylogging++.h"
namespace LQF
{
NaluLoop::NaluLoop(int queue_nalu_len):
    max_nalu_(queue_nalu_len), Looper()
{
    audio_back_pts = audio_front_pts = video_back_pts = video_fromt_pts = 0;
    audio_packet_nb = video_packet_nb = 0;
}

//队列里面既有音频，也有视频
void NaluLoop::addmsg(LooperMessage *msg, bool flush)
{
    queue_mutex_.lock();
    if (flush) {
        msg_queue_.clear();
    }
    if(audio_front_pts - audio_back_pts > 500 || video_fromt_pts - video_back_pts > 500){
        if(msg_queue_.size() >= 0) { //移除消息,直到下一个I帧，或者队列为空
            while(msg_queue_.size() > max_nalu_) {
                LooperMessage *tempMsg =  msg_queue_.front();
                // 从I帧开始, 5代码I帧 nalu type
                if(tempMsg->what == RTMP_BODY_VID_RAW && ((NaluStruct*)tempMsg->obj)->type & 0x1f ) {
                    LOG(WARNING) << "drop msg, now have " << msg_queue_.size() << " frame";
                    LOG(WARNING) << "audio packet: " << audio_packet_nb << " video packet: " << video_packet_nb;
                    break;
                }
                msg_queue_.pop_front();
                if(tempMsg->what == RTMP_BODY_VID_RAW){
                    NaluStruct* nalu = (NaluStruct*)tempMsg->obj;
                    video_fromt_pts = nalu->pts;
                    video_packet_nb--;
                }else if(tempMsg->what == RTMP_BODY_AUD_RAW){
                    AudioRawMsg* aud = (AudioRawMsg*)tempMsg->obj;
                    audio_front_pts = aud->pts;
                    audio_packet_nb--;
                }
                delete tempMsg->obj;
                delete tempMsg;
            }
        }
    }
    msg_queue_.push_back(msg);
    if(msg->what == RTMP_BODY_VID_RAW){
        video_packet_nb++;
        NaluStruct* nalu = (NaluStruct*)msg->obj;
        video_back_pts = nalu->pts;
    }
    if(msg->what == RTMP_BODY_AUD_RAW){
        audio_packet_nb++;
        AudioRawMsg* aud = (AudioRawMsg*)msg->obj;
        audio_back_pts = aud->pts;
    }
    if(msg_queue_.size() > max_nalu_ / 3) {
        LOG(WARNING) << "have " << msg_queue_.size() << " msg cache, it will cause delay";
        LOG(WARNING) << "video dur " << video_back_pts - video_fromt_pts << " ms " << video_packet_nb << " packet";
        LOG(WARNING) << "audio dur " << audio_back_pts - audio_front_pts << " ms " << audio_packet_nb<< " packet";
    }
    queue_mutex_.unlock();
    head_data_available_->post();
}
}
